package com.tyoj.tyojbackendquestionservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tyoj.model.dto.postthumb.QuestionThumbAddRequest;
import com.tyoj.model.dto.questionSubmit.QuestionSubmitQueryRequest;
import com.tyoj.model.entity.Question;
import com.tyoj.model.entity.QuestionThumb;
import com.tyoj.model.entity.User;
import com.tyoj.model.enums.QuestionSubmitLanguageEnum;
import com.tyoj.model.enums.QuestionSubmitStatusEnum;
import com.tyoj.model.vo.QuestionSubmmitVO;
import com.tyoj.tyojbackendclient.service.JudgeFeignClient;
import com.tyoj.tyojbackendclient.service.UserFeignClient;
import com.tyoj.tyojbackendcommon.common.ErrorCode;
import com.tyoj.tyojbackendcommon.constant.CommonConstant;
import com.tyoj.tyojbackendcommon.exception.BusinessException;
import com.tyoj.tyojbackendcommon.utils.SqlUtils;
import com.tyoj.tyojbackendquestionservice.mapper.QuestionThumbMapper;
import com.tyoj.tyojbackendquestionservice.rabbitmq.MyMessageProducer;
import com.tyoj.tyojbackendquestionservice.service.QuestionService;
import com.tyoj.tyojbackendquestionservice.service.QuestionThumbService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * @author WangJiyou
 * @description 针对表【question_thumb(题目提交)】的数据库操作Service实现
 * @createDate 2024-06-06 11:14:32
 */
@Service
public class QuestionThumbServiceImpl extends ServiceImpl<QuestionThumbMapper, QuestionThumb> implements QuestionThumbService {

    @Resource
    private QuestionService questionService;

    @Resource
    private UserFeignClient userService;

    @Resource
    @Lazy
    private JudgeFeignClient judgeService;

    @Resource
    private MyMessageProducer myMessageProducer;

    /**
     * 提交题目
     *
     * @param questionSubmitAddRequest
     * @param loginUser
     * @return
     */
    @Override
    public Long doQuestionThumb(QuestionThumbAddRequest questionSubmitAddRequest, User loginUser) {
        // 校验编程语言是否合法
        String language = questionSubmitAddRequest.getLanguage();
        QuestionSubmitLanguageEnum languageEnum = QuestionSubmitLanguageEnum.getEnumByValue(language);
        if (languageEnum == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "编程语言错误");
        }
        long questionId = questionSubmitAddRequest.getQuestionId();
        // 判断实体是否存在，根据类别获取实体
        Question question = questionService.getById(questionId);
        if (question == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        // 是否已提交题目
        long userId = loginUser.getId();
        // 每个用户串行提交题目
        QuestionThumb questionSubmit = new QuestionThumb();
        questionSubmit.setUserId(userId);
        questionSubmit.setQuestionId(questionId);
        questionSubmit.setCode(questionSubmitAddRequest.getCode());
        questionSubmit.setLanguage(language);
        // 设置初始状态
        questionSubmit.setStatus(QuestionSubmitStatusEnum.WAITING.getValue());
        boolean save = this.save(questionSubmit);
        if (!save) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "数据插入失败");
        }
        Long questionSubmitId = questionSubmit.getId();
        //发送消息
        myMessageProducer.sendMessage("code_exchange", "my_routingKey", String.valueOf(questionId));
        // 执行判题服务
//        CompletableFuture.runAsync(() -> {
//            QuestionThumb questionThumb = judgeService.doJudge(questionSubmitId);
//            this.updateById(questionThumb);
//        });
        return questionSubmitId;
    }


    /**
     * 封装了事务的方法
     *
     * @param userId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int doQuestionThumbInner(long userId, QuestionThumbAddRequest questionThumbAddRequest) {
        QuestionThumb questionThumb = new QuestionThumb();
        Long questionId = questionThumbAddRequest.getQuestionId();
        questionThumb.setUserId(userId);
        questionThumb.setQuestionId(questionId);
        QueryWrapper<QuestionThumb> thumbQueryWrapper = new QueryWrapper<>(questionThumb);
        QuestionThumb oldQuestionThumb = this.getOne(thumbQueryWrapper);
        boolean result;
        if (oldQuestionThumb != null) {
            result = this.remove(thumbQueryWrapper);
            if (result) {
                result = questionService.update().eq("id", questionId).gt("thumbNum", 0).setSql("thumbNum = thumbNum - 1").update();
                return result ? -1 : 0;
            } else {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR);
            }
        } else {
            result = this.save(questionThumb);
            if (result) {
                result = questionService.update().eq("id", questionId).setSql("thumbNum = thumbNum + 1").update();
                return result ? 1 : 0;
            } else {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR);
            }
        }
    }

    @Override
    public QueryWrapper<QuestionThumb> getQueryWrapper(QuestionSubmitQueryRequest questionSubmitQueryRequest, User userLogin) {
        QueryWrapper<QuestionThumb> queryWrapper = new QueryWrapper<>();
        if (questionSubmitQueryRequest == null) {
            return queryWrapper;
        }
        //提交语言
        String language = questionSubmitQueryRequest.getLanguage();
        //状态
        Integer status = questionSubmitQueryRequest.getStatus();
        //问题id
        Long questionId = questionSubmitQueryRequest.getQuestionId();
        //用户ID
        Long userId = questionSubmitQueryRequest.getUserId();
        //排序字段,排序顺序
        String sortField = questionSubmitQueryRequest.getSortField();
        String sortOrder = questionSubmitQueryRequest.getSortOrder();

        // 拼接查询条件
        queryWrapper.eq(StringUtils.isNotBlank(language), "language", language);
        queryWrapper.eq(ObjectUtils.isNotEmpty(userId), "userId", userId);
        queryWrapper.eq(ObjectUtils.isNotEmpty(questionId), "questionId", questionId);
        queryWrapper.eq(QuestionSubmitStatusEnum.getEnumByValue(status) != null, "status", status);
        queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC), sortField);
        return queryWrapper;
    }

    @Override
    public QuestionSubmmitVO getQuestionSubmmitVo(QuestionThumb questionThumb, User loginUser) {
        QuestionSubmmitVO questionSubmmitVO = new QuestionSubmmitVO();
        Long userId = loginUser.getId();
        questionSubmmitVO = questionSubmmitVO.objToVo(questionThumb);
        if (userId != questionSubmmitVO.getUserId() && !userService.isAdmin(loginUser)) questionSubmmitVO.setCode(null);

        return questionSubmmitVO;
    }
}




